#include "HkpWorld.h"

namespace Havok
{
	namespace Dynamics
	{
		HkpWorld::HkpWorld(HkpWorldCinfo^ info)
		{
			info->m_worldCinfo->setBroadPhaseWorldSize(1000.0f);
			info->m_worldCinfo->m_broadPhaseBorderBehaviour = info->m_worldCinfo->BROADPHASE_BORDER_FIX_ENTITY;
			m_world = new hkpWorld(*(info->m_worldCinfo));

			//m_world->markForWrite();

			hkpAgentRegisterUtil::registerAllAgents(m_world->getCollisionDispatcher());

			RigidBodies = gcnew System::Collections::Generic::List<HkpRigidBody^>();

			{
				hkMemory::getInstance().preAllocateRuntimeBlock(512000, HK_MEMORY_CLASS_BASE);
				hkMemory::getInstance().preAllocateRuntimeBlock(256000, HK_MEMORY_CLASS_BASE);
				hkMemory::getInstance().preAllocateRuntimeBlock(128000, HK_MEMORY_CLASS_BASE);
				hkMemory::getInstance().preAllocateRuntimeBlock(64000, HK_MEMORY_CLASS_BASE);
				hkMemory::getInstance().preAllocateRuntimeBlock(32000, HK_MEMORY_CLASS_BASE);
				hkMemory::getInstance().preAllocateRuntimeBlock(16000, HK_MEMORY_CLASS_BASE);
				hkMemory::getInstance().preAllocateRuntimeBlock(16000, HK_MEMORY_CLASS_BASE);
			}

			//hkpMultithreadingUtilCinfo threadInfo;
			//threadInfo.m_world = m_world;
			//threadInfo.m_numThreads = 1;

			//threadInfo.m_enableTimers = true;

			//multithreadingUtil = new hkpMultithreadingUtil(threadInfo);


			//m_world->unmarkForWrite();
		}

		HkpWorld::~HkpWorld()
		{
			m_world->removeReference();
		}

		HkpStepResult HkpWorld::Update(GameTime^ gameTime)
		{
			
			if (gameTime->ElapsedGameTime.TotalSeconds == 0)
				m_world->stepDeltaTime(0.01f);
			else
				m_world->stepDeltaTime((float)gameTime->ElapsedGameTime.TotalSeconds);
			
			//double time = gameTime->ElapsedGameTime.TotalSeconds;
			//if (time.CompareTo(0)==0) time = 0.01;
			//
			//m_world->resetThreadTokens();

			//multithreadingUtil->startStepWorld((float)time);

			//multithreadingUtil->waitForStepWorldFinished();
			
			return HkpStepResult::StepResultSuccess;
		}

		void HkpWorld::AddEntity(HkpRigidBody^ entity)
		{
			//m_world->markForWrite();
			m_world->addEntity(entity->m_native);
			//RigidBodies->Add(entity);
			//m_world->unmarkForWrite();
		}

		void HkpWorld::RemoveEntity(HkpRigidBody^ entity)
		{
			//RigidBodies->Remove(entity);
			m_world->removeEntity(entity->m_native);
		}

		void HkpWorld::AddPhantom(Phantom::HkpPhantom ^phantom)
		{
			m_world->addPhantom(phantom->m_phantom);
		}
	}
}
